package modelo.util;

import java.lang.Math;

import ar.uba.fi.algo3.titiritero.Posicionable;
import static modelo.SetUps.TOLERANCIA;

public class Vector implements Posicionable{

	private float x;
	private float y;
	
	public Vector(float coordx, float coordy){
		x = coordx;
		y = coordy;
	}

	public Vector multiplicar(float numero){
		float resultx = x * numero;
		float resulty = y * numero;
		return new Vector(resultx, resulty);
	}
	
	public Vector dividir(float numero){
		if (numero == 0) throw new ArithmeticException();
		return this.multiplicar(1/numero);
	}
	
	public Vector sumar(Vector v){
		float resultx = x + v.getx();
		float resulty = y + v.gety();
		return new Vector(resultx, resulty);
	}
	
	public Vector restar(Vector v){
		return this.sumar(v.multiplicar(-1));
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + Float.floatToIntBits(x);
		result = prime * result + Float.floatToIntBits(y);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) 
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Vector other = (Vector) obj;
		if (Math.abs(this.x - other.x) > TOLERANCIA)
			return false;
		if (Math.abs(this.y- other.y) > TOLERANCIA)
			return false;
		return true;
	}
	
	public float getx(){
		return x;
	}
	
	public float gety(){
		return y;
	}
	
	public void setCoordenadas(float coordx, float coordy){
		x = coordx;
		y = coordy;
	}
	
	public float angulo(Vector v){
		if ( ( (v.getx() == 0) && (v.gety() == 0) ) || ( (x == 0) && (y == 0) ) ){
			throw new ArithmeticException();		
		}
		/* Vieja implementacion
		float div1 = y;
		if (x != 0) div1 = y/x;
		float div2 = v.gety();
		if (x != 0) div2 = v.gety()/v.getx();		
		return (float) ( Math.atan(div1) - Math.atan(div2) );
		*/
		return (float) ( Math.atan2(x,y) - Math.atan2(v.getx(),v.gety()) );
	}

	public float norma(){
		return (float)( Math.sqrt( x*x + y*y ) );
	}
	
	public Vector direccion(Vector v){
		return v.restar(this);
	}
	
	public float distancia(Vector v){
		return this.restar(v).norma();
	}
	
	public Vector rotar(double radianes){
		//Devuelve el vector resultado de rotar el vector en radianes en sentido antihorario.
		return new Vector( (float)(x * Math.cos(radianes) - y * Math.sin(radianes) ),
				(float)(x * Math.sin(radianes) + y * Math.cos(radianes) ) );
	}
	
	public Vector versor(){
		return this.dividir(this.norma());
	}
	
	public String toString(){
        return ( "[" + x + "," + y + "]");
    }
    
    public static Vector parseVector(String s){
            String x = "";
            String y = "";
            boolean primero = false;
            boolean segundo = false;
            for (int i = 0 ; i < s.length() ; i++) {
                    if ( s.charAt(i) == ']') break;
                    else if ( s.charAt(i) == ',') {
                            primero = false;
                            segundo = true;
                            continue;
                    }
                    else if ( s.charAt(i) == '[') {
                            primero = true;
                            continue;
                    }
                    if (primero) x = x+s.charAt(i);
                    else if (segundo) y = y+s.charAt(i);
            }
            return new Vector ( Float.parseFloat(x), Float.parseFloat(y));
	}
	
	public Vector obtenerCopia(){
		return new Vector(x,y);
	}
	
	//Interface
	public int getX(){
		return (int)x;
	}
	
	public int getY(){
		return (int)y;
	}
		
}